From 9f5d73a99b722d513ab7bdbe71311da625358f14 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Wed, 29 Aug 2018 17:35:33 +0200 Subject: [PATCH] base: add single precision versions of all gray reference code --- babl/base/model-gray.c | 711 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 711 insertions(+) diff --git a/babl/base/model-gray.c b/babl/base/model-gray.c index 33df8dc..a5cbe31 100644 --- a/babl/base/model-gray.c +++ b/babl/base/model-gray.c @@ -28,6 +28,7 @@ static void components (void); static void models (void); static void conversions (void); static void formats (void); +static void init_single_precision (void); void babl_base_model_gray (void) { @@ -35,6 +36,7 @@ void babl_base_model_gray (void) models (); conversions (); formats (); + init_single_precision (); } static void @@ -893,3 +895,712 @@ formats (void) babl_component_from_id (BABL_GRAY_NONLINEAR), NULL); } + +/********** float versions ***********/ + +static void +rgba_to_graya_float (Babl *conversion, + char *src, + char *dst, + long n) +{ + const Babl *space = babl_conversion_get_source_space (conversion); + float RGB_LUMINANCE_RED = space->space.RGBtoXYZf[3]; + float RGB_LUMINANCE_GREEN = space->space.RGBtoXYZf[4]; + float RGB_LUMINANCE_BLUE = space->space.RGBtoXYZf[5]; + + while (n--) + { + float red, green, blue; + float luminance, alpha; + + red = ((float *) src)[0]; + green = ((float *) src)[1]; + blue = ((float *) src)[2]; + alpha = ((float *) src)[3]; + + luminance = red * RGB_LUMINANCE_RED + + green * RGB_LUMINANCE_GREEN + + blue * RGB_LUMINANCE_BLUE; + + ((float *) dst)[0] = luminance; + ((float *) dst)[1] = alpha; + + src += sizeof (float) * 4; + dst += sizeof (float) * 2; + } +} + +static void +rgba_to_gray_float (Babl *conversion, + char *src, + char *dst, + long n) +{ + const Babl *space = babl_conversion_get_source_space (conversion); + float RGB_LUMINANCE_RED = space->space.RGBtoXYZf[3]; + float RGB_LUMINANCE_GREEN = space->space.RGBtoXYZf[4]; + float RGB_LUMINANCE_BLUE = space->space.RGBtoXYZf[5]; + + while (n--) + { + float red, green, blue; + float luminance; + + red = ((float *) src)[0]; + green = ((float *) src)[1]; + blue = ((float *) src)[2]; + + luminance = red * RGB_LUMINANCE_RED + + green * RGB_LUMINANCE_GREEN + + blue * RGB_LUMINANCE_BLUE; + + ((float *) dst)[0] = luminance; + + src += sizeof (float) * 4; + dst += sizeof (float) * 1; + } +} + +static void +rgb_to_gray_nonlinear_float (Babl *conversion, + int src_bands, + char **src, + int *src_pitch, + int dst_bands, + char **dst, + int *dst_pitch, + long n) +{ + const Babl *space = babl_conversion_get_destination_space (conversion); + const Babl *trc = space->space.trc[0]; + float RGB_LUMINANCE_RED = space->space.RGBtoXYZf[3]; + float RGB_LUMINANCE_GREEN = space->space.RGBtoXYZf[4]; + float RGB_LUMINANCE_BLUE = space->space.RGBtoXYZf[5]; + + BABL_PLANAR_SANITY + while (n--) + { + float red, green, blue; + float luminance, alpha; + + red = *(float *) src[0]; + green = *(float *) src[1]; + blue = *(float *) src[2]; + if (src_bands > 3) + alpha = *(float *) src[3]; + else + alpha = 1.0; + + luminance = red * RGB_LUMINANCE_RED + + green * RGB_LUMINANCE_GREEN + + blue * RGB_LUMINANCE_BLUE; + *(float *) dst[0] = babl_trc_from_linear (trc, luminance); + + if (dst_bands == 2) + *(float *) dst[1] = alpha; + + BABL_PLANAR_STEP + } +} + + +static void +gray_nonlinear_to_rgb_float (Babl *conversion, + int src_bands, + char **src, + int *src_pitch, + int dst_bands, + char **dst, + int *dst_pitch, + long n) +{ + const Babl *space = babl_conversion_get_source_space (conversion); + const Babl *trc = space->space.trc[0]; + + BABL_PLANAR_SANITY + while (n--) + { + float luminance; + float red, green, blue; + float alpha; + + luminance = babl_trc_to_linear (trc, *(float *) src[0]); + red = luminance; + green = luminance; + blue = luminance; + if (src_bands > 1) + alpha = *(float *) src[1]; + else + alpha = 1.0; + + *(float *) dst[0] = red; + *(float *) dst[1] = green; + *(float *) dst[2] = blue; + + if (dst_bands > 3) + *(float *) dst[3] = alpha; + + BABL_PLANAR_STEP + } +} + +static void +rgb_to_gray_perceptual_float (Babl *conversion, + int src_bands, + char **src, + int *src_pitch, + int dst_bands, + char **dst, + int *dst_pitch, + long n) +{ + const Babl *space = babl_conversion_get_destination_space (conversion); + const Babl *trc = perceptual_trc; + float RGB_LUMINANCE_RED = space->space.RGBtoXYZf[3]; + float RGB_LUMINANCE_GREEN = space->space.RGBtoXYZf[4]; + float RGB_LUMINANCE_BLUE = space->space.RGBtoXYZf[5]; + + BABL_PLANAR_SANITY + while (n--) + { + float red, green, blue; + float luminance, alpha; + + red = *(float *) src[0]; + green = *(float *) src[1]; + blue = *(float *) src[2]; + if (src_bands > 3) + alpha = *(float *) src[3]; + else + alpha = 1.0; + + luminance = red * RGB_LUMINANCE_RED + + green * RGB_LUMINANCE_GREEN + + blue * RGB_LUMINANCE_BLUE; + *(float *) dst[0] = babl_trc_from_linear (trc, luminance); + + if (dst_bands == 2) + *(float *) dst[1] = alpha; + + BABL_PLANAR_STEP + } +} + +static void +gray_perceptual_to_rgb_float (Babl *conversion, + int src_bands, + char **src, + int *src_pitch, + int dst_bands, + char **dst, + int *dst_pitch, + long n) +{ + const Babl *trc = perceptual_trc; + + BABL_PLANAR_SANITY + while (n--) + { + float luminance; + float red, green, blue; + float alpha; + + luminance = babl_trc_to_linear (trc, *(float *) src[0]); + red = luminance; + green = luminance; + blue = luminance; + if (src_bands > 1) + alpha = *(float *) src[1]; + else + alpha = 1.0; + + *(float *) dst[0] = red; + *(float *) dst[1] = green; + *(float *) dst[2] = blue; + + if (dst_bands > 3) + *(float *) dst[3] = alpha; + + BABL_PLANAR_STEP + } +} + + +static void +graya_to_rgba_float (Babl *conversion, + char *src, + char *dst, + long n) +{ + while (n--) + { + float luminance; + float red, green, blue; + float alpha; + + luminance = ((float *) src)[0]; + alpha = ((float *) src)[1]; + red = luminance; + green = luminance; + blue = luminance; + + ((float *) dst)[0] = red; + ((float *) dst)[1] = green; + ((float *) dst)[2] = blue; + ((float *) dst)[3] = alpha; + + src += sizeof (float) * 2; + dst += sizeof (float) * 4; + } +} + + +static void +gray_to_rgba_float (Babl *conversion, + char *src, + char *dst, + long n) +{ + while (n--) + { + float luminance; + float red, green, blue; + + luminance = ((float *) src)[0]; + red = luminance; + green = luminance; + blue = luminance; + + ((float *) dst)[0] = red; + ((float *) dst)[1] = green; + ((float *) dst)[2] = blue; + ((float *) dst)[3] = 1.0; + + src += sizeof (float) * 1; + dst += sizeof (float) * 4; + } +} + +static void +gray_alpha_premultiplied_to_rgba_float (Babl *conversion, + int src_bands, + char **src, + int *src_pitch, + int dst_bands, + char **dst, + int *dst_pitch, + long n) +{ + BABL_PLANAR_SANITY + assert (src_bands == 2); + assert (dst_bands == 4); + + while (n--) + { + float luminance = *(float *) src[0]; + float alpha; + alpha = *(float *) src[1]; + if (alpha == 0) + luminance = 0; + else + { + luminance = luminance / alpha; + if (alpha == BABL_ALPHA_FLOOR || alpha == -BABL_ALPHA_FLOOR) + alpha = 0.0; + } + + *(float *) dst[0] = luminance; + *(float *) dst[1] = luminance; + *(float *) dst[2] = luminance; + *(float *) dst[3] = alpha; + BABL_PLANAR_STEP + } +} + + +static void +rgba_to_gray_alpha_premultiplied_float (Babl *conversion, + int src_bands, + char **src, + int *src_pitch, + int dst_bands, + char **dst, + int *dst_pitch, + long n) +{ + const Babl *space = babl_conversion_get_source_space (conversion); + float RGB_LUMINANCE_RED = space->space.RGBtoXYZf[3]; + float RGB_LUMINANCE_GREEN = space->space.RGBtoXYZf[4]; + float RGB_LUMINANCE_BLUE = space->space.RGBtoXYZf[5]; + + BABL_PLANAR_SANITY; + assert (src_bands == 4); + assert (dst_bands == 2); + + while (n--) + { + float red = *(float *) src[0]; + float green = *(float *) src[1]; + float blue = *(float *) src[2]; + float luminance; + float alpha = *(float *) src[3]; + if (alpha <= BABL_ALPHA_FLOOR) + { + if (alpha >= 0.0f) + alpha = BABL_ALPHA_FLOOR; + else if (alpha >= -BABL_ALPHA_FLOOR) + alpha = -BABL_ALPHA_FLOOR; + if (red == 0.0 && green == 0.0 && blue == 0.0) + alpha = 0.0; + } + + luminance = red * RGB_LUMINANCE_RED + + green * RGB_LUMINANCE_GREEN + + blue * RGB_LUMINANCE_BLUE; + + luminance *= alpha; + + *(float *) dst[0] = luminance; + *(float *) dst[1] = alpha; + BABL_PLANAR_STEP + } +} + +static void +non_premultiplied_to_premultiplied_float (Babl *conversion, + int src_bands, + char **src, + int *src_pitch, + int dst_bands, + char **dst, + int *dst_pitch, + long n) +{ + BABL_PLANAR_SANITY + + while (n--) + { + int band; + float alpha = *(float *) src[src_bands-1]; + if (alpha < BABL_ALPHA_FLOOR) + { + int non_zero_components = 0; + if (alpha >= 0.0f) + alpha = BABL_ALPHA_FLOOR; + else if (alpha >= -BABL_ALPHA_FLOOR) + alpha = -BABL_ALPHA_FLOOR; + + for (band = 0; band < src_bands - 1; band++) + { + if (*(float *) src[band] != 0.0) + non_zero_components++; + } + if (non_zero_components) + alpha = 0.0; + + } + + for (band = 0; band < src_bands - 1; band++) + { + *(float *) dst[band] = *(float *) src[band] * alpha; + } + *(float *) dst[dst_bands - 1] = alpha; + + BABL_PLANAR_STEP + } +} + +static void +premultiplied_to_non_premultiplied_float (Babl *conversion, + int src_bands, + char **src, + int *src_pitch, + int dst_bands, + char **dst, + int *dst_pitch, + long n) +{ + BABL_PLANAR_SANITY + + while (n--) + { + int band; + float alpha; + alpha = *(float *) src[src_bands-1]; + + for (band = 0; band < src_bands - 1; band++) + { + if (alpha == 0.0) + *(float *) dst[band] = 0; + else + *(float *) dst[band] = *(float *) src[band] / alpha; + } + if (alpha == BABL_ALPHA_FLOOR || alpha == -BABL_ALPHA_FLOOR) + alpha = 0.0; + *(float *) dst[dst_bands - 1] = alpha; + + BABL_PLANAR_STEP + } +} + +static void +rgba2gray_nonlinear_premultiplied_float (Babl *conversion, + char *src, + char *dst, + long n) +{ + const Babl *space = babl_conversion_get_destination_space (conversion); + const Babl *trc = space->space.trc[0]; + float RGB_LUMINANCE_RED = space->space.RGBtoXYZf[3]; + float RGB_LUMINANCE_GREEN = space->space.RGBtoXYZf[4]; + float RGB_LUMINANCE_BLUE = space->space.RGBtoXYZf[5]; + + while (n--) + { + float red = ((float *) src)[0]; + float green = ((float *) src)[1]; + float blue = ((float *) src)[2]; + float luminance; + float luma; + float alpha = ((float *) src)[3]; + if (alpha < BABL_ALPHA_FLOOR) + { + if (alpha >= 0.0f) + alpha = BABL_ALPHA_FLOOR; + else if (alpha >= -BABL_ALPHA_FLOOR) + alpha = -BABL_ALPHA_FLOOR; + if (red == 0.0 && green == 0.0 && blue == 0.0) + alpha = 0.0; + } + + luminance = red * RGB_LUMINANCE_RED + + green * RGB_LUMINANCE_GREEN + + blue * RGB_LUMINANCE_BLUE; + luma = babl_trc_from_linear (trc, luminance); + + ((float *) dst)[0] = luma * alpha; + ((float *) dst)[1] = alpha; + + src += 4 * sizeof (float); + dst += 2 * sizeof (float); + } +} + +static void +gray_nonlinear_premultiplied2rgba_float (Babl *conversion, + char *src, + char *dst, + long n) +{ + const Babl *space = babl_conversion_get_destination_space (conversion); + const Babl *trc = space->space.trc[0]; + + while (n--) + { + float luma = ((float *) src)[0]; + float luminance; + float alpha; + alpha = ((float *) src)[1]; + if (alpha == 0.0) + luma = 0.0; + else + luma = luma / alpha; + + luminance = babl_trc_to_linear (trc, luma); + + if (alpha == BABL_ALPHA_FLOOR || alpha == -BABL_ALPHA_FLOOR) + alpha = 0.0; + + ((float *) dst)[0] = luminance; + ((float *) dst)[1] = luminance; + ((float *) dst)[2] = luminance; + ((float *) dst)[3] = alpha; + + src += 2 * sizeof (float); + dst += 4 * sizeof (float); + } +} + +static void init_single_precision (void) +{ + babl_format_new ( + babl_model ("Y"), + babl_type_from_id (BABL_FLOAT), + babl_component ("Y"), + NULL); + babl_format_new ( + babl_model ("Y'"), + babl_type_from_id (BABL_FLOAT), + babl_component ("Y'"), + NULL); + babl_format_new ( + babl_model ("Y~"), + babl_type_from_id (BABL_FLOAT), + babl_component ("Y~"), + NULL); + + + babl_format_new ( + babl_model ("YA"), + babl_type_from_id (BABL_FLOAT), + babl_component ("Y"), + babl_component ("A"), + NULL); + babl_format_new ( + babl_model ("Y'A"), + babl_type_from_id (BABL_FLOAT), + babl_component ("Y'"), + babl_component ("A"), + NULL); + babl_format_new ( + babl_model ("Y~A"), + babl_type_from_id (BABL_FLOAT), + babl_component ("Y~"), + babl_component ("A"), + NULL); + + + babl_format_new ( + babl_model ("YaA"), + babl_type_from_id (BABL_FLOAT), + babl_component ("Ya"), + babl_component ("A"), + NULL); + babl_format_new ( + babl_model ("Y'aA"), + babl_type_from_id (BABL_FLOAT), + babl_component ("Y'a"), + babl_component ("A"), + NULL); + + babl_conversion_new ( + babl_format ("Y' float"), + babl_format ("RGBA float"), + "planar", gray_nonlinear_to_rgb_float, + NULL + ); + + babl_conversion_new ( + babl_format ("RGBA float"), + babl_format ("Y' float"), + "planar", rgb_to_gray_nonlinear_float, + NULL + ); + + babl_conversion_new ( + babl_format ("Y'A float"), + babl_format ("RGBA float"), + "planar", gray_nonlinear_to_rgb_float, + NULL + ); + + babl_conversion_new ( + babl_format ("RGBA float"), + babl_format ("Y'A float"), + "planar", rgb_to_gray_nonlinear_float, + NULL + ); + + + babl_conversion_new ( + babl_format ("Y'aA float"), + babl_format ("RGBA float"), + "linear", gray_nonlinear_premultiplied2rgba_float, + NULL + ); + + babl_conversion_new ( + babl_format ("RGBA float"), + babl_format ("Y'aA float"), + "linear", rgba2gray_nonlinear_premultiplied_float, + NULL + ); + + + + babl_conversion_new ( + babl_format ("Y~ float"), + babl_format ("RGBA float"), + "planar", gray_perceptual_to_rgb_float, + NULL + ); + + babl_conversion_new ( + babl_format ("RGBA float"), + babl_format ("Y~ float"), + "planar", rgb_to_gray_perceptual_float, + NULL + ); + + babl_conversion_new ( + babl_format ("Y~A float"), + babl_format ("RGBA float"), + "planar", gray_perceptual_to_rgb_float, + NULL + ); + + babl_conversion_new ( + babl_format ("RGBA float"), + babl_format ("Y~A float"), + "planar", rgb_to_gray_perceptual_float, + NULL + ); + + + babl_conversion_new ( + babl_format ("YA float"), + babl_format ("RGBA float"), + "linear", gray_to_rgba_float, + NULL + ); + + babl_conversion_new ( + babl_format ("YA float"), + babl_format ("RGBA float"), + "linear", graya_to_rgba_float, + NULL + ); + + babl_conversion_new ( + babl_format ("RGBA float"), + babl_format ("YA float"), + "linear", rgba_to_graya_float, + NULL + ); + + babl_conversion_new ( + babl_format ("RGBA float"), + babl_format ("Y float"), + "linear", rgba_to_gray_float, + NULL + ); + + babl_conversion_new ( + babl_format ("YA float"), + babl_format ("YaA float"), + "planar", non_premultiplied_to_premultiplied_float, + NULL + ); + + babl_conversion_new ( + babl_format ("YaA float"), + babl_format ("YA float"), + "planar", premultiplied_to_non_premultiplied_float, + NULL + ); + + babl_conversion_new ( + babl_format ("YaA float"), + babl_format ("RGBA float"), + "planar", gray_alpha_premultiplied_to_rgba_float, + NULL + ); + + babl_conversion_new ( + babl_format ("RGBA float"), + babl_format ("YaA float"), + "planar", rgba_to_gray_alpha_premultiplied_float, + NULL + ); +} -- 2.30.2